#include "mockcpp/mockcpp.hpp"
#include "practice.h"
#include "pub.h"
#include "gtest/gtest.h"
#include <iostream>
#include <stdio.h>

// setuptestcase fixture
// setup everycase

extern "C" {
extern void HandleFuncOfLazyExec();
extern int  MockFooInit();
extern int  MockFooSendPersonMsg();
extern int  FooSndMsg(void *msgHdr, int msgLen);
extern int MockFooAllMsgProc(void *msgHdr, int msgLen);
}

class LearnMockcppTest : public ::testing::Test {
  protected:
    virtual void SetUp() { std::cout << "setup executor" << std::endl; }
    virtual void TearDown()
    {
        std::cout << "teardown executor" << std::endl;
        GlobalMockObject::verify();
    }
    static void SetUpTestCase() { std::cout << "setup by case" << std::endl; }
    static void TearDownTestCase()
    {
        std::cout << "teardown by case" << std::endl;
    }
};

TEST_F(LearnMockcppTest, learn01_mock)
{
    // MOCKER(printf).stubs().expects(once());
    MOCKER(HandleFuncOfLazyExec).expects(once());
    LazyExecForOnce();
    LazyExecForOnce();
}

TEST_F(LearnMockcppTest, learn01_stub)
{
    // MOCKER(printf).stubs().expects(once());
    // MOCKER(HandleFuncOfLazyExec).expects(once());
    // LazyExecForOnce();
    // LazyExecForOnce();
}

TEST_F(LearnMockcppTest, learn01_spy)
{
    // MOCKER(printf).stubs().expects(once());
    // MOCKER(HandleFuncOfLazyExec).expects(once());
    // LazyExecForOnce();
    // LazyExecForOnce();
}

TEST_F(LearnMockcppTest, learn01_fake)
{
    // MOCKER(printf).stubs().expects(once());
    // MOCKER(HandleFuncOfLazyExec).expects(once());
    // LazyExecForOnce();
    // LazyExecForOnce();
}

int FakeFooSndMsg(void *msgHdr, int msgLen)
{
    printf("get msg %p, msgLen(%d)\n", msgHdr, msgLen);
    return MockFooAllMsgProc(msgHdr, msgLen);
}

TEST_F(LearnMockcppTest, learn02_fake)
{
    // MOCKER(printf).stubs().expects(once());
    // MOCKER(HandleFuncOfLazyExec).expects(once());
    // LazyExecForOnce();
    // LazyExecForOnce();

    MockFooInit();
    MOCKER(FooSndMsg).stubs().will(invoke(FakeFooSndMsg));
    MockFooSendPersonMsg();
}
